/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.sdt.ontology;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import edu.yonsei.iwb.sdt.util.SDTLog;

/**
 *
 * @author DK
 */
public class ResourceWeights extends Hashtable<Resource, Double>{
    private Model model;
    
    public ResourceWeights(Model model){
        this.model = model;    
        SDTLog.log(SDTLog.DETAIL, "# Initialize property weights\n");
        initializePropertyWeights();
    }
    
    public ResourceWeights(){        
    }
       
//    public double get(Property p){
//        if(this.containsKey(p)){
//            return this.get(p);
//        }else{
//            double w = calculatesWeight(p);
//            this.put(p, w);
//            return w;
//        }
//    }
    
//    private double calculatesWeight(Property p){
//        return 0;
//    }
    
    private void initializePropertyWeights() {
        Vector<Resource> empty = new Vector<Resource>();
        int countOfProperties = 0;
        ResourceWeights tempProperty = new ResourceWeights();
        ResIterator ri = this.model.listSubjectsWithProperty(RDF.type, OWL.ObjectProperty);
        while (ri.hasNext()) {
            Property property = ResourceFactory.createProperty(ri.next().getURI());
            ResIterator tripleOfProperty = this.model.listResourcesWithProperty(property);
            int count = this.count(tripleOfProperty);
            if (count == 0) {
                empty.add(property);
            } else {
                countOfProperties += count;
                tempProperty.put(property, (double) count);
            }
        }
        this.update(tempProperty, countOfProperties);
        this.updateEmptySet(empty);
    }
    
    private void updateEmptySet(@SuppressWarnings("UseOfObsoleteCollectionType") Vector<Resource> empty) {
        for (int i = 0; i < empty.size(); i++) {
            SDTLog.log(SDTLog.DETAIL, "# \"" + empty.get(i)+"\" ,  0.0\n");
            this.put(empty.get(i), 0.0);
        }
    }
    
    private void update(ResourceWeights weights, int totalCount) {
        for (int i = 0; i < UncountedResources.SET.size(); i++) {
            String r = UncountedResources.SET.get(i);
            if (weights.containsKey(r)) {
                double count = weights.get(r);
                totalCount -= count;
                weights.remove(UncountedResources.SET.get(i));
            }
        }
        
        ResourceWeights temp = new ResourceWeights();
        Enumeration<Resource> keys = weights.keys();
        while (keys.hasMoreElements()) {
            Resource key = keys.nextElement();
            double value = weights.get(key);
            temp.put(key, (value / totalCount));
        }
        this.putAll(Normalization.normalizeByMinMax(temp));
    }
    
    private int count(ResIterator ri) {
        int result = 0;
        while (ri.hasNext()) {
            result++;
            ri.next();
        }
        return result;
    }

    private int count(StmtIterator si) {
        int result = 0;
        while (si.hasNext()) {
            result++;
            si.next();
        }
        return result;
    }
        
}
